package com.itheima.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.dao.MenuDao;
import com.itheima.dao.RoleDao;
import com.itheima.entity.PageResult;
import com.itheima.exceptions.BusinessException;
import com.itheima.pojo.Menu;
import com.itheima.pojo.Role;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author W.J.Y
 */
@Service(version = "1.0.0",interfaceClass = MenuService.class)
@Transactional
public class MenuServiceImpl implements MenuService{

    @Resource
    private MenuDao menuDao;
    @Resource
    private RoleDao roleDao;


    /**
     * 新增菜单
     * @param menu  菜单实例
     * @throws BusinessException    可能出现的业务异常
     */
    @Override
    public void add(Menu menu) throws BusinessException {
        Integer count = menuDao.findByLinkUrl(menu);
        if(count>0){
            throw new BusinessException("已存相同链接的菜单，添加失败！");
        }
        //首先添加菜单
        menuDao.add(menu);
        //再添加菜单与角色的关联
        Integer id = menu.getId();
        Set<Integer> roleIds = menu.getRoleIds();
        if (roleIds!=null){
            for (Integer roleId : roleIds) {
                menuDao.setMenuAndRole(id,roleId);
            }
        }
    }

    /**
     * 编辑菜单
     * @param menu 菜单实例
     * @throws BusinessException    可能出现的业务异常
     */
    @Override
    public void update(Menu menu) throws BusinessException {
        Integer count = menuDao.findByLinkUrl(menu);
        if(count>0){
            throw new BusinessException("已存相同链接的菜单，编辑失败！");
        }
        menuDao.update(menu);
        //首先删除菜单与角色旧的关联关系
        menuDao.deleteRoleSByMenuId(menu.getId());
        //再添加菜单与角色的关联
        Integer id = menu.getId();
        Set<Integer> roleIds = menu.getRoleIds();
        if (roleIds!=null){
            for (Integer roleId : roleIds) {
                //添加关系关联
                menuDao.setRoleAndMenu(id,roleId);
            }
        }
    }

    /**
     * 根据菜单级别查询菜单信息
     * @param level 菜单级别
     * @return  菜单级别下菜单信息
     */
    @Override
    public List<Menu> findByLevel(int level) {
        return menuDao.findByLevel(level);
    }

    /**
     * 删除菜单
     * @param id    菜单ID
     * @throws BusinessException 可能出现的业务异常
     */
    @Override
    public void delete(int id) throws BusinessException {
        Role role = roleDao.findRoleByMenuId(id);
        if (role!=null){
            throw new BusinessException("菜单已被角色"+role.getName()+"绑定，请先解绑！");
        }
        menuDao.delete(id);
    }

    /**
     * 分页查询菜单信息
     * @param pageNum   当前页
     * @param pageSize  每页显示条数
     * @param queryString   查询语句
     * @return  菜单分页信息
     */
    @Override
    public PageResult findPage(int pageNum, int pageSize, String queryString) {
        //开启分页查询
        PageHelper.startPage(pageNum,pageSize);
        //调用dao层查询语句
        Page<Menu> page = menuDao.findPage(queryString);
        List<Menu> result = page.getResult();
        for (int i = 0; i < result.size(); i++) {
            Menu menu = result.get(i);
            int id = menu.getId();
            //根据菜单ID查询角色
            Set<Role> roles = roleDao.findRolesByMenuId(id);
            //将角色赋值给菜单
            menu.setRoles(roles);
            //根据菜单ID查询所有子菜单,赋值给菜单
            List<Menu> childrens = menuDao.findChildrenById(id);
            //将子菜单赋值给菜单
            menu.setChildren(childrens);
            //根据菜单ID查询父菜单
            Menu parentMenu = menuDao.findParentMenuById(id);
            //将父菜单赋值给菜单
            if (parentMenu!=null) {
                menu.setParentMenu(parentMenu);
                menu.setParentMenuId(menu.getId());
            }
        }
        //封装分页查询结果对象
        return new PageResult(page.getTotal(),result);
    }

    /**
     * 根据ID查询菜单信息
     * @param id    菜单ID
     * @return  返回结果
     */
    @Override
    public Menu findById(int id) {
        //根据ID查询菜单
        Menu menu = menuDao.findById(id);
        //根据菜单ID查询角色
        Set<Role> roles = roleDao.findRolesByMenuId(id);
        //将角色赋值给菜单
        menu.setRoles(roles);
        //将角色ID赋值给菜单
        Set<Integer> roleIds = new HashSet<>();
        for (Role role : roles) {
            roleIds.add(role.getId());
        }
        menu.setRoleIds(roleIds);
        //根据菜单ID查询所有子菜单,赋值给菜单
        List<Menu> childrens = menuDao.findChildrenById(id);
        //将子菜单赋值给菜单
        menu.setChildren(childrens);
        //根据菜单ID查询父菜单
        Menu parentMenu = menuDao.findParentMenuById(id);
        //将父菜单赋值给菜单
        if (parentMenu!=null) {
            menu.setParentMenu(parentMenu);
            menu.setParentMenuId(parentMenu.getId());
        }
        return menu;
    }

    /**
     * 查询全部菜单信息
     * @return  全部菜单信息
     */
    @Override
    public List<Menu> findAll() {
        return menuDao.findAll();
    }
}
